package com.cgah

import grails.converters.JSON

/**
 * Ok, i'll entertain grails convention of integration tests
 * Man these guys really need better define their class
 * Why does a integration test get called 'GroovyTestCase'?
 * Wouldn't that imply that it's a unit test, not an integration test?
 */
// Grails automatically configures each test with a MockHttpServletRequest, MockHttpServletResponse, and MockHttpSession
class ListingControllerTests extends AbstractIntegrationTest {
    def static buyer;
    def static seller;
    def static Listing listing;

    /** Setup metaclass fixtures for mocking.   */
    void setUp() {
        super.setUp()
        setupForClass(ListingController.newInstance());
        // create a customer
        def userRole = com.cgah.Role.findByAuthority(Constants.ROLE_USER) ?: new Role(authority: Constants.ROLE_USER).save(failOnError: true)

        // create users and give them user role
        buyer = User.findByUsername('buyer') ?:
            new Customer(
                    username: "buyer",
                    emailAddress: "buyer@test.com",
                    password: "boooya", //springSecurityService.encodePassword('boooya', null),
                    createdDate: new Date(),
                    enabled: true).save(failOnError: true)
        if (!buyer.getAuthorities().contains(userRole)) {
            UserRole.create(buyer, userRole)
        }


        seller = User.findByUsername('seller') ?:
            new Customer(
                    username: "seller",
                    emailAddress: "seller@test.com",
                    password: "boooya", //springSecurityService.encodePassword('boooya', null),
                    createdDate: new Date(),
                    enabled: true).save(failOnError: true)
        if (!seller.getAuthorities().contains(userRole)) {
            UserRole.create(seller, userRole)
        }
        // create the listing for the seller
        listing = new Listing(name: "bling bling", startingBidPrice: 10.0, seller: seller, endDateTime: new Date() + 6, createdDateTime: new Date() - 6).save(failOnError: true, flush: true);

        // create the bids for the buyer
        Calendar calendar = Calendar.getInstance();
        for (int i = 0; i < 15; i++) {
            calendar.add(Calendar.MINUTE, 1);
            // have to save so they go in order
            new Bid(dateTime: new Date(calendar.timeInMillis), amount: 12 + i, nextMinBid: 12 + i + 0.5, customer: buyer, listing: listing).save(failOnError: true, flush: true);
        }
        println "All Z bids: " + Bid.findAllByListing(listing);
    }

    protected void tearDown() {
        super.tearDown()
    }

    /*
     * UI-1: The listing detail page will asynchronously load and display a list of the last 10 bids placed on the item
     * showing the user, date/time, and amount. The implementation of the lookup of these results
     * must be done with a Named Query. (Integration Test)
     * IDK what (Integration Test) here really means?  We are testing that named query gets called when we ask for
     * the last ten?  And that we get something back?
     * So we insert a bunch of bids, then call lastTen and expect to get the last ten back right?
     * OK, close enough i guess
     */
    void testLastTenBids_return_the_correct_data() {
        def controller = new ListingController();
        params = [id: listing.id];
        controller.lastTenBids();  // grails is so stupid!
        def result = controller.response.contentAsString; // grails is SOOO STUPID
        def jsonStr = JSON.parse(result) // GRAILS IS SOO STUPID ALL THIS COULD OF BEEN IN ONE WRAPPER METHOD

        def queryBids = Bid.findAllByListing(listing, [max: 10, sort: "id", order: "desc"]);
        assert (jsonStr.size() == 10)

        for (int i = 0; i < 10; i++) {
            assertEquals("success", jsonStr[i].id, queryBids.get(i).id);
        }

    }
}
